package com.atguigu.netty.inboundhandlerandoutboundhandler;

import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.MessageToByteEncoder;

import java.util.List;

/**
 * TODO
 * @author wuzz
 * @since 2024/7/15
 */
public class MyServer {
    public static void main(String[] args) {


        EventLoopGroup boss = new NioEventLoopGroup(1);
        EventLoopGroup worker = new NioEventLoopGroup(1);

        ServerBootstrap serverBootstrap = new ServerBootstrap();

        try {
            serverBootstrap.group(boss, worker)
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            // 入站解码器
                            pipeline.addLast(new ByteToMessageDecoder() {
                                /**
                                 * decode会根据接收的数据，被调用多次，直到确定没有新的元素被添加到list中
                                 * 或者bytebuf没有更多可读的字节为止
                                 * 如果list out不为空，就会将list内容传递给下一个channelinboundhandler处理
                                 * 该处理器也会被调用多次
                                 * @param ctx
                                 * @param in
                                 * @param out
                                 * @throws Exception
                                 */
                                @Override
                                protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
                                    System.out.println("服务端解码器被调用");
                                    if (in.readableBytes() >= 8) {
                                        out.add(in.readLong());
                                    }
                                }
                            });

                            // 出站编码器
                            pipeline.addLast(new MessageToByteEncoder<Long>() {
                                @Override
                                protected void encode(ChannelHandlerContext ctx, Long msg, ByteBuf out) throws Exception {
                                    System.out.println("服务端编码器");
                                    out.writeLong(msg);
                                }
                            });

                            // 自己的业务逻辑
                            pipeline.addLast(new MyServerHandler());
                        }
                    });
            ChannelFuture sync = serverBootstrap.bind(8888).sync();
            sync.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }


}
